﻿using System;
using System.Collections.Generic;
using System.Text;
using ExpressionUtil.Parser;
using ExpressionUtil.Node;

namespace ExpressionUtil.Extension
{
    /// <summary>
    /// 扩展函数
    /// </summary>
    public class ExtensionFunction
    {
        /// <summary>
        /// 扩展函数名称
        /// </summary>
        private string functionName;

        /// <summary>
        /// 参数个数类型
        /// </summary>
        private ParameterCountType parameterCountType;

        /// <summary>
        /// 参数个数
        /// </summary>
        private int parameterCount;

        /// <summary>
        /// 扩展函数的回调委托
        /// </summary>
        private ExtensionFuncionHandler callbackHandler;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="name">扩展函数名称</param>
        /// <param name="handler">扩展函数的回调委托</param>
        public ExtensionFunction(string name, ExtensionFuncionHandler handler)
            : this(name, ParameterCountType.Fixed, 0, handler)
        {
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="name">扩展函数名称</param>
        /// <param name="countType">参数个数类型</param>
        /// <param name="parameterCount">参数个数</param>
        /// <param name="handler">扩展函数的回调委托</param>
        public ExtensionFunction(string name, ParameterCountType countType, int parameterCount, ExtensionFuncionHandler handler)
        {
            this.FunctionName = name;
            this.CallbackHandler = handler;
            this.ParameterCountType = countType;
            this.ParameterCount = parameterCount;
        }

        /// <summary>
        /// 获取或设置扩展函数名称
        /// </summary>
        public string FunctionName
        {
            get
            {
                return this.functionName;
            }
            set
            {
                if (string.IsNullOrEmpty(value))
                {
                    throw new InvalidOperationException("Function name must be not null or empty.");
                }
                this.functionName = value;
            }
        }

        /// <summary>
        /// 获取或设置参数个数类型
        /// </summary>
        public ParameterCountType ParameterCountType
        {
            get
            {
                return this.parameterCountType;
            }
            set
            {
                this.parameterCountType = value;
            }
        }

        /// <summary>
        /// 获取或设置参数个数
        /// </summary>
        public int ParameterCount
        {
            get
            {
                //if (this.parameterCountType == ParameterCountType.Variable)
                //{
                //    throw new InvalidOperationException("Parameter count type is variable,can't get parameter count.");
                //}
                return this.parameterCount;
            }
            set
            {
                if (this.parameterCountType == ParameterCountType.Variable)
                {
                    throw new InvalidOperationException("Parameter count type is variable,can't set parameter count.");
                }
                if (value < 0)
                {
                    throw new InvalidOperationException("Parameter count must be greater or equal than zero.");
                }
                this.parameterCount = value;
            }
        }

        /// <summary>
        /// 获取或设置扩展函数的回调委托
        /// </summary>
        public ExtensionFuncionHandler CallbackHandler
        {
            get
            {
                return this.callbackHandler;
            }
            set
            {
                if (value == null)
                {
                    throw new InvalidOperationException("Function callback handler must be not null.");
                }
                this.callbackHandler = value;
            }
        }

        /// <summary>
        /// 注册扩展函数，在调用时必须没有其他线程在执行编译操作和注册、注销操作
        /// </summary>
        /// <param name="function">扩展函数</param>
        public static void Register(ExtensionFunction function)
        {
            string functionName = "Function_" + function.functionName.ToLower() + "(";
            if (ParseContext.CreateHandlerMap.ContainsKey(functionName) || ParseContext.ExtFunctionMap.ContainsKey(functionName))
            {
                throw new InvalidOperationException("Register function already exists.");
            }
            ParseContext.CreateHandlerMap.Add(functionName, ExtensionFunctionNode.CreateExtensionFunctionNode);
            ParseContext.ExtFunctionMap.Add(functionName, function);
        }

        /// <summary>
        /// 注销扩展函数，在调用时必须没有其他线程在执行编译操作和注册、注销操作
        /// </summary>
        /// <param name="functionName">扩展函数名称</param>
        public static void Unregister(string functionName)
        {
            string name = "Function_" + functionName.ToLower() + "(";
            if (ParseContext.CreateHandlerMap.ContainsKey(name))
            {
                ParseContext.CreateHandlerMap.Remove(name);
            }
            if (ParseContext.ExtFunctionMap.ContainsKey(name))
            {
                ParseContext.ExtFunctionMap.Remove(name);
            }
        }
    }
}
